#include "tserver.h"
#include "tsocket.h"
#include "teventloop.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

namespace tlib
{
#ifdef WIN32
	TEventLoop::TEventLoop()
	{
		FD_ZERO(&connSet_);
		timeout_.tv_sec = 0;
		timeout_.tv_usec = 500;
		holdfd_ = ::socket(AF_INET, SOCK_STREAM, 0);
		FD_SET(holdfd_, &connSet_);
	}

	TEventLoop::~TEventLoop()
	{
		::closesocket(holdfd_);
	}

	bool TEventLoop::AddLoop(TSocket* sock)
	{
		std::cout << "threadid[" << std::this_thread::get_id() << "] addLoop, because sockfd " << sock->fd() << std::endl;
		FD_SET(sock->fd(), &connSet_);
		cliMap[sock->fd()] = sock;
		return true;
	}

	bool TEventLoop::DelLoop(TSocket* sock)
	{
		std::cout << "threadid[" << std::this_thread::get_id() << "] delLoop, because sockfd " << sock->fd() << std::endl;
		FD_CLR(sock->fd(), &connSet_);
		return true;
	}

	void TEventLoop::RunLoop(TServer* server)
	{
		for (;;)
		{
			FD_ZERO(&sendSet_);
			FD_ZERO(&recvSet_);
			sendSet_ = connSet_;
			recvSet_ = connSet_;
			int ret = ::select(0, &recvSet_, /*&sendSet_*/NULL, NULL, &timeout_);
			for (int i = 0; i < connSet_.fd_count; i++)
			{
				if (FD_ISSET(connSet_.fd_array[i], &recvSet_))
				{
					server->PreRecv(cliMap[connSet_.fd_array[i]]);
				}
			}
		}
	}

#else
	TEventLoop::TEventLoop()
	{
		epollfd_ = ::epoll_create(MAX_EVENTS);
		holdfd_ = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
		if (epollfd_ < 0) log_exit("epoll_create出错, exit");
	}

	TEventLoop::~TEventLoop()
	{
		close(epollfd_);
		close(holdfd_);
	}

	bool TEventLoop::AddLoop(TSocket* sock)
	{
		ev_.events = EPOLLIN;
		ev_.data.ptr = sock;
		if (-1 == ::epoll_ctl(epollfd_, EPOLL_CTL_ADD, sock->fd(), &ev_)) log_exit("epoll_ctl出错, exit");
	}

	bool TEventLoop::DelLoop(TSocket* sock)
	{
		ev_.events = EPOLLIN;
		ev_.data.ptr = sock;
		if (-1 == ::epoll_ctl(epollfd_, EPOLL_CTL_DEL, sock->fd(), &ev_)) log_exit("epoll_ctl出错, exit");
	}

	void TEventLoop::RunLoop(TServer* server)
	{
		for (;;)
		{
			int fds = ::epoll_wait(epollfd_, events_, MAX_EVENTS, -1);
			for (int i = 0; i < fds; i++)
			{
				if (events_[i].events & EPOLLIN)
				{
					//printf("events.ptr->fd(): %d, server.serSock_.fd(): %d\n", ((TSocket*)events[i].data.ptr)->fd(), server->serSock_.fd());
					TSocket* sock = (TSocket*)events_[i].data.ptr;
					server->PreRecv(sock);
				}
				else
				{

				}
			}
		}
	}
#endif
}